classdef CloudSimulate < handle

    properties
        model=[];
    end
    
    methods
        
        function obj=CloudSimulate()
            addpath('opera'); 
            addpath('xml_io_tools');
            model=OpModel();            
        end
        
        % 10 PMs different capacities
        % 1 container on each  
        % 1 class of user
        % variable workload                         
        function buildtest(obj,model)
            model.services=[OpService('BrowserClient','ClientContainer')]; 
            num=11;
            for i=1:num
                model.services=[model.services,  OpService(sprintf('BrowseService%d',i),...
                                                                        sprintf('Container%d',i))]; 
            end

            for i=1:num
                model.calls=[model.calls...
                    OpCall('BrowserClient', sprintf('BrowseService%d',i), 1/num, 1.3207, 0)]
            end            
            model.scenarios=OpScenario('select','BrowserClient',model.calls);

            model.nodes= [OpNode('ClientHost','client',1,1)];
            for i=1:num
                model.nodes=[model.nodes,  OpNode(sprintf('Host%d',i),'server',2,1)]; 
            end
                       
            model.containers=[OpContainer('ClientContainer', 1000, 'ClientHost', 'false' )];            
            for i=1:num
                model.containers=[model.containers,   OpContainer(sprintf('Container%d',i), 400, sprintf('Host%d',i), 'true' )];  
            end           
            model.clusters=[OpCluster('ClientCluster',[model.containers(1)]),...
                            OpCluster('WebCluster',[model.containers(2:end)])]; 
                            

             scWorkloads=containers.Map({'select'},{OpClosedWorkload(100,0.1)});            
             model.workload = OpWorkload(100,scWorkloads);         
                          
             nodes = ['ClientHost ']; 
             for i=1:num
                nodes=[nodes sprintf('Host%d ',i)];
             end
            model.networks = OpNetwork(nodes); 
             
        end

                % 10 PMs different capacities
        % 1 container on each  
        % 1 class of user
        % variable workload                         
        function buildtest2(obj,model,server_num, total_demand,num_users)      
            model.services=[OpService('BrowserClient','ClientContainer')]; 
            model.nodes= [OpNode('ClientHost','client',1,1)];
            model.containers=[OpContainer('ClientContainer', 1000, 'ClientHost', 'false' )];            
            nodes = ['ClientHost ']; 

            model.services=[model.services, OpService('BrowserLB','LBContainer')]; 
            model.nodes= [model.nodes, OpNode('LBHost','server',1,1)];
            model.containers=[model.containers, OpContainer('LBContainer', 1000, 'LBHost', 'true' )];            
            nodes = [nodes, 'LBHost ']; 
            model.calls=[model.calls...
                    OpCall('BrowserClient' , 'BrowserLB' , 1, 0, 0)]; 
                       
            i=1;
            total_servers = sum(server_num); 
            for server_type=1:size(server_num,2)
                for j=1:server_num(server_type)
                    

                    model.services=[model.services,  OpService(sprintf('BrowseService%d',i),...
                                                                            sprintf('Container%d',i))]; 
                    model.calls=[model.calls...
                        OpCall('BrowserLB', sprintf('BrowseService%d',i), 1, total_demand/total_servers, 0)]; 

                    cu=prices_amz().get_compute_units;
                    cpuParallelism = cu(server_type);
                    model.nodes=[model.nodes,  OpNode(sprintf('Host%d',i),'server', cpuParallelism ,1)]; 
                    model.containers=[model.containers,   OpContainer(sprintf('Container%d',i), 400, sprintf('Host%d',i), 'true' )];  
                    nodes=[nodes sprintf('Host%d ',i)];
                    i=i+1; 
                end           
            end
            model.scenarios=OpScenario('select','BrowserClient',model.calls);
            model.clusters=[OpCluster('ClientCluster',[model.containers(1)]),...
                            OpCluster('WebCluster',[model.containers(2:end)])];                             

             scWorkloads=containers.Map({'select'},{OpClosedWorkload(num_users,0.1)});            
             model.workload = OpWorkload(num_users,scWorkloads);         
             model.networks = OpNetwork(nodes);              
        end

        % CloudSimulate().testIaaS()
        function util_=testIaaS(obj)
            instance_quantity_to_fire=[0 4 0 0 0 0 0 0 0 0 0 ]; 
            opM=OpModel();
            obj.buildtest2(opM,instance_quantity_to_fire,1.4);
            opM.solve(); 
            
            util = [];
            for i=3:length(opM.nodes)
                util=[util opM.nodes(i).cpuUtilization];
            end
            util_ = mean(util);
        end
        
    end %methods
end

